import java.util.*;


public class DB_Messungen{
	//----------------------------VAR------------------------	
	//Logging//
	Logger loggeriz0r = new Logger();
	//Datei
	Datei d = new Datei();
	//Create a standard user with no name//
	protected User user;
	protected Messstation mstation;
	//Storage//
	protected ArrayList<Messung> db = new ArrayList<Messung>();
	//-----------------------------VAR_end-------------------
	public DB_Messungen()
	{
		//Create our standard user//
		this.user = new User();
		//And standard messstation//
		this.mstation = new Messstation();
		
		this.loggeriz0r.addLog("Programm gestartet!",this.mstation.getID());
		//-----------------------Laden----------------------
		String m_db = d.Laden("Messung.ser");
		String [] abc = m_db.split("\n");
		//werte
			double mess;
			String Einheit;
			Calendar Datum;
			String Institut_Bez;
			int Institut_Nr;
			String Einheit_Bez;
			
		//Messung add var
			Messung tempmess;
			String [] data;
			
		if(abc.length != 1)
		{
			for(int i=0;i<abc.length;i++)
			{
				data = abc[i].split(" ");
				Einheit_Bez = 				data[0];
				mess 	= 		new Double(data[1]);
				Einheit = 					data[2];
				Datum = 	 create_Date_ob(abc[i]);
				Institut_Bez = 				data[5];
				Institut_Nr = 	new Integer(data[6]);
				
				//Messung erzeugen
					tempmess = new Messung(Einheit_Bez,mess,Einheit,Datum,Institut_Bez,Institut_Nr);
				//Save in ArrayList
					boolean a  = db.add(tempmess);
					if(!a)
						this.loggeriz0r.addLog("Fehler:Daten wurden nicht erfolgreich geladen",this.mstation.getID());
			}
		}		
	}
	//--------------Einlesen der Einzelnen Daten-------------
	public String einlesen(String Eingabe)
	{		
		//-----------------------var-------------------------
		//Rueckgabe 
			String out = "";
		
		//Werte
			String [] data;
			double mess;
			String Einheit = "";
			Calendar Datum = new GregorianCalendar();
			String Institut_Bez = "";
			int Institut_Nr;
			String Einheit_Bez;
		
		//Temp_Messung
			Messung tempmess;
		
		//-----------------------var end--------------------
		
		//Ueberpruefung auf Richtigkeit der Eingabe
			String e_ueberpruefung = Eingabe_ueberpruefung(Eingabe);
		    if(!e_ueberpruefung.equals("OK"))
		    {
		    	this.loggeriz0r.addLog("Einlesen neuere Var:Falsches Einagbeformat",this.mstation.getID());
		    	return "Eingabe des Datums bzw. der Zeit bitte auf DD-MM-YY HH:MM:SS aendern\n";
		    }
		    else
		    	this.loggeriz0r.addLog("Einlesen neuere Var:Ueberpruefung OK",this.mstation.getID());
		    	
		
		//Backup der old_db
			String bak = d.bak("bak_db_e","Messung.ser");
			if(!bak.equals("OK"))
			{
				this.loggeriz0r.addLog("Einlesen neuere Var: Konnte Bak nicht erstellen",this.mstation.getID());
				return "Konnte Bak nicht erstellen\n"; 
			}
			else
				this.loggeriz0r.addLog("Einlesen neuere Var: Backup erfolgreich erstellt",this.mstation.getID());
			
		//Umwandlung 
				data = Eingabe.split(" ");
				Einheit_Bez = data[0];
				mess = new Double(data[1]);
				Einheit = (data[2]);
				Datum = create_Date_ob(Eingabe);
				Institut_Bez = (data[5]);
				Institut_Nr = new Integer(data[6]);
		//Ueberpruefen der Doppel...
			for(int q = 0; q < db.size(); q++)
			{
				if(db.get(q).getYear() == Datum.get(Calendar.YEAR) && db.get(q).getMonth() == Datum.get(Calendar.MONTH) && db.get(q).getDay() == Datum.get(Calendar.DAY_OF_MONTH) && db.get(q).getMessungstyp().equals(Einheit_Bez))
					return "Messung gleich\n";
			}
		
		//**********new********** Mess Ueberpruefung
			if(mess < 1)
				return "Messung unter 0\n";
				
		//Ueberpruefung der Nebenbedingungen
				String e_nebenbedingung = Eingabe_nebenbedingung(Eingabe,Einheit);
				if(e_ueberpruefung.equals("Fail"))
				{
					return "Der Messwert wurde schon erfasst bzw. Fehler beim Grenzwert";
				}
				else
					out = out + e_nebenbedingung;
		//Messung erzeugen + Save in db
			tempmess = new Messung(Einheit_Bez,mess,Einheit,Datum,Institut_Bez,Institut_Nr);
			db.add(tempmess);
		//Speichern der new_db
			String save = d.Speichern("Messung.ser",Laden_db());
			if(!save.equals("OK"))
				return "Konnte Datei nicht Speichern\n";
				
		//Add Log//
		this.loggeriz0r.addLog(out,this.mstation.getID());
		return out+"\n";
			
	}
	//--------------Ueberpruefung auf richtige Eingabe-------
	private String Eingabe_ueberpruefung(String datensatz)
	{	
		//String Erzeugung
		String [] data = datensatz.split(" ");
		
		//**********new**********
		int day		= 	new Integer(data[3].substring(0,2));
	    int month 	= 	new Integer(data[3].substring(3,5));
	    if(!(day>0 && day<32)&& !(month>0 && month<13))
	    {
	    	return "Fail";
	    }	    
	    //Ueberpruefung der Trennzeichen --> Datum
	    if(!data[3].substring(2,3).equals(".")|| !data[3].substring(5,6).equals("."))
	    {
	    	return "Fail";
	    }
	    //**********new**********
	    int hour 	= 	new Integer(data[4].substring(0,2));
	    int minute 	= 	new Integer(data[4].substring(3,5));
	    int seconds = 	new Integer(data[4].substring(6,8));
	    if(!(hour>0 && hour<25)&& !(minute>0 && minute<61) && !(seconds>0 && seconds<61))
	    {
	    	return "Fail";
	    }	    
	    //Ueberpruefung der Trennzeichen --> Uhrzeit
	    if(!data[4].substring(2,3).equals(":")|| !data[4].substring(5,6).equals(":"))
	    {
	    	return "Fail";
	    }	  
		return "OK";
	}
	//--------------Ueberpruefung der Werte------------------ 
	private String Eingabe_nebenbedingung(String datensatz,String Einheit)
	{
		//erzeugen der Einheiten 
		Einheiten_DB e = new Einheiten_DB();
		
		//Rueckgabe
		String out = "";
			
		//Grenzwert = 100 angen.
		int Grenzwert = e.getGrenzwert(Einheit);
		if(Grenzwert == 0)
			return "Fail";
		
		//Datensatz Aufteilung
		int mess;
		
		int year;
		int month;
		int day;
		
		int hours;
		int minutes;
		
		//Vorigen Werte
		double vWert = 0;
		
		//Laufvar fuer die Anzahl aller Datensaetz in der letzen Std
		int d_anz = 0;
		//Laufvar fuer die Werte die den Messwert uebersteigen in der letzen std
		int d1_anz = 0;
		
		//Eingabe Spliten
		String [] data = datensatz.split(" ");		
		//Wert der Messung auslesen
		mess = new Integer(data[1]);
		
		//Auslesen der Daten(DD:MM:YY) aus date
		String [] d = data[3].split("\\.");
	    day 	 =  new Integer(d[0]);
	    month 	 = 	new Integer(d[1]);
	    year 	 = 	new Integer(d[2]);
	    //Auslesen der Daten(hh:mm:ss) aus time
	    String [] t = data[4].split(":");
	    hours   = 	new Integer(t[0]);
	    minutes = 	new Integer(t[1]);
	    
	    //---------------Der gerade erfasste Messwert("+mess+") ist mehr als doppelt so hoch wie der Grenzwert
	    if(mess >= 2 * Grenzwert)
	    {
	    	out = out + "\n"+"Der gerade erfasste Messwert("+mess+") ist mehr als doppelt so hoch wie der Grenzwert.";
	    }  
	    //---------------Die letzten beiden Messwerte("+mess+","+vWert+") uebersteigen jeweils den Grenzwert
	    if(db.size()>= 2 )
	    {
	    	//vorigen Wert(einheit) aus db auslesen
	    	for(int a=db.size()-1;a>=0;a--)
	    	{
	    		if(db.get(a).getEinheit() == Einheit)
	    		{
	    			vWert = db.get(a).getMess();
	    			break;
	    		}
	    	}
	    	if(vWert != 0)
	    		if(vWert>new Double(Grenzwert) && mess >new Double(Grenzwert))
	    			out = out + "\n"+ "Die letzten beiden Messwerte("+mess+","+vWert+") uebersteigen jeweils den Grenzwert.";
	    	
	    }
	    //---------------Mehr als die Haelfte der innerhalb der letzten Stunde gemessenen Werte uebersteigt den Grenzwert, vorausgesetzt es hat in diesem Zeitraum mindestens fuenf Messungen gegeben
	    //neu int bei jedem durchlauf (1 wegen dem gerade Erfassten Wert)
	    if(mess>100)
	    {
	    	d1_anz = 1;
	    }else
	    {
	    	d1_anz = 0;
	    }
	    for(int z=0;z<db.size();z++)
	    {
	    	if(db.get(z).getEinheit() == Einheit)
	    	{	
	    		if(db.get(z).getDay() == day && db.get(z).getMonth() == month && db.get(z).getYear() == year)
	    		{
	    			if(db.get(z).getHours() == hours-1 && db.get(z).getMinutes() > minutes)
	    			{
		    			d_anz++;
		    			if(db.get(z).getMess() >new Double(Grenzwert))
		    			{
		    				d1_anz++;
		    			}
		    		}else if(db.get(z).getHours() == hours && db.get(z).getMinutes() < minutes)
		    		{
		    			d_anz++;
		    			if(db.get(z).getMess() >new Double(Grenzwert))
		    			{
		    				d1_anz++;
		    			}
		    		}
		    			
		    	}
		    	else if(hours == 00 && db.get(z).getDay() == day-1 && db.get(z).getMonth() == month && db.get(z).getYear() == year)
		    	{
		    		
		    		if(db.get(z).getHours() == 23 && db.get(z).getMinutes() > minutes)
		    		{
		    			d_anz++;
		    			if(db.get(z).getMess() >new Double(Grenzwert))
		    			{
		    				d1_anz++;
		    			}
		    		}else if(db.get(z).getHours() == hours && db.get(z).getMinutes() < minutes)
		    		{
		    			d_anz++;
		    			if(db.get(z).getMess() >new Double(Grenzwert))
		    			{
		    				d1_anz++;
		    			}
		    			
		    		}
		    	}	
	    	}
	    }
	    double d2_anz = new Double (d_anz);
	    double d3_anz = new Double (d1_anz);
	    if(d_anz >=5)
	    {
	    	if(d3_anz > (d2_anz/2))
	    	{
	    		out = out + "\n"+"Mehr als die Haelfte der innerhalb der letzten Stunde gemessenen Werte uebersteigt den Grenzwert";
	    	}
	    }
	    //Es gibt bereits eine Messung mit gleicher Uhrzeit + gleiches Datum//
	    
	    //Add the log with name//
	    this.loggeriz0r.addLog(this.user.getName()+ ": " + out,this.mstation.getID());
	    
		return out;
	}
	//--------------Wandelt String in -----------------------
	protected Calendar create_Date_ob(String datensatz)
	{
		//Datumsformat
		Calendar Datum = Calendar.getInstance();

		//Datensatz Aufteilung
		int year = 00;
		int month = 00;
		int day = 00;
		
		int hours = 00;
		int minutes = 00;
		int seconds = 00;
		//Nur Datum oder Uhrzeit
		if(datensatz.length() == 8)
		{
			if(datensatz.substring(2,3).equals("."))
			{
				
				//Auslesen der Daten(DD.MM.YY) aus date
				String d = datensatz.substring(0,8);
			    day 	 =  new Integer(d.substring(0,2));
			    month 	 = 	new Integer(d.substring(3,5));
			    year 	 = 	new Integer(d.substring(6,8));
			    
			}else if(datensatz.substring(2,3).equals(":"))
			{
				//Auslesen der Daten(hh:mm:ss) aus time
			    String t = datensatz.substring(0,8);
			    hours 	 = 	new Integer(t.substring(0,2));
			    minutes = 	new Integer(t.substring(3,5));
			    seconds = 	new Integer(t.substring(6,8));
			}
		}
		//Datum und Uhrzeit
		else if(datensatz.length() == 18)
		{
			
			//Auslesen der Daten(DD.MM.YY) aus date
			String d = datensatz.substring(0,8);
		    day 	 =  new Integer(d.substring(0,2));
		    month 	 = 	new Integer(d.substring(3,5));
		    year 	 = 	new Integer(d.substring(6,8));
		    
		    //Auslesen der Daten(hh:mm:ss) aus time
		    String t = datensatz.substring(9,18);
		    hours 	 = 	new Integer(t.substring(0,2));
		    minutes = 	new Integer(t.substring(3,5));
		    seconds = 	new Integer(t.substring(6,8));
		}
		//alles
		else
		{
			//Date und time aus eingabe
			String [] data = datensatz.split(" ");
			
			//Auslesen der Daten(DD.MM.YY) aus date
			String [] d = data[3].split("\\.");
		    day 	 =  new Integer(d[0]);
		    month 	 = 	new Integer(d[1]);
		    year 	 = 	new Integer(d[2]);
		    
		    //Auslesen der Daten(hh:mm:ss) aus time
		    String [] t = data[4].split(":");
		    hours 	 = 	new Integer(t[0]);
		    minutes = 	new Integer(t[1]);
		    seconds = 	new Integer(t[2]);
		}
			Datum.set(year, month, day, hours, minutes, seconds);
		    
	    return Datum;
	}
	//--------------Rueckgabe der DB--------------------------
	private ArrayList<Messung> getdb()
	{
		return db;
	
	}
    
	//--------------db in String-----------------------------
	protected String Laden_db()
	{
		String out="";
		for(int i=0;i<this.db.size();i++)
		{
			out = out + this.db.get(i).getall()+"\n";
		}
		return out;
	}
	//--------------User-authentication----------------------
	protected void authentication(String username, String password)
	{
		/*
		 * Erstellt ein neues user objekt und validiert dieses auf gueltigkeit
		 * WEnn gueltig -> Admin 1, wenn nicht, 0
		 */
		this.user = new User(username, password);
	}
	
	/*
	 * Authentifiziert den user als messstation
	 * Wenn authenti nix gut geht => id 0
	 */
	protected void login(int id, String password)
	{
		this.mstation = new Messstation(password, id);
	}

}